home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
282_01
/
walclock.c
< prev
next >
Wrap
Text File
|
1989-01-11
|
18KB
|
870 lines
/*
TITLE: Wall Clock;
DATE: 9/19/88;
DESCRIPTION: "Analog clock face.";
VERSION: 1.10;
KEYWORDS: Clock, Graphics, HGA, Hercules;
FILENAME: WALCLOCK.C
WARNINGS: "Requires Hercules monochrome graphics.";
SEE-ALSO: WALCLOCK.DAT, WALCLOCK.EXE;
SYSTEM: MS-DOS;
COMPILERS: Aztec;
AUTHORS: Dan Schechter;
*/
#include <stdio.h>
#include <time.h>
#include <math.h>
#define TICKTOCK /* Delete this if you don't want the tick-tock. */
#define NOMATH /* Delete this if the program will always be
run on a computer with a floating-point coprocessor
and your compiler has FPU support. With NOMATH
defined, the program uses a table look-up to
position the hands. This makes the program about twice
as large. If NOMATH is not defined, the program
calculates the positions of hands on the fly, but
an FPU is necessary if this is to be done fast enough
to keep up with real time. */
#ifdef TICKTOCK
#include <signal.h>
#endif
#ifdef NOMATH
#define VERSION "Version 1.10-t 9/19/88"
#else
#define VERSION "Version 1.10-fpu 9/19/88"
#endif
#define CENTERH 360
#define CENTERV 174
#define TOPH 360
#define TOPV 25
#define LONG 125
#define SHORT 75
#define INDEXPORT 0x3B4
#define CONTROLPORT 0x3b8
#define DATAPORT 0x3b5
#define CONFIGPORT 0x3bf
#define SCREEN0 0xb0000 /* Absolute address for page 0. */
#define SCREEN1 0xb8000 /* Absolute address for page 1. */
#define ROMFONT 0xffa6e /* Absolute address of IBM ROM character set. */
void drawclock(void), controller(void), line(int,int,int,int,int),
gocircle(int,int), _drawclock(void),
hand(int,int,int,int,int), writetd(int,int,int,int, struct tm *),
markers(void), g_write(char *,int,int), sigexit(int), cleardot(int,int),
reagantime(struct tm *), chinatime(void), menu(void),
stepclock(void), writedot(int,int), g_putch(int,int,int), sw_scr(int),
g_mode(void), t_mode(void), *abstoptr(unsigned long),
tick(void), soundon(void), soundoff(void), tick_init(void);
int sqroot(long);
char *day[7] = {
"Sunday ",
"Monday ",
"Tuesday ",
"Wednesday",
"Thursday ",
"Friday ",
"Saturday "
};
char *month[12] = {
"January ",
"February ",
"March ",
"April ",
"May ",
"June ",
"July ",
"August ",
"September ",
"October ",
"November ",
"December "
};
int gdata[12] = {
0x35, 0x2d, 0x2e, 0x7, 0x5b, 0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0
};
int tdata[12] = {
0x61, 0x50, 0x52, 0xf, 0x19, 0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc
};
int h24[24] = { 53, 61, 68, 73, 76, 77, 76, 73, 69, 60, 52, 44,
36, 28, 21, 16, 13, 12, 13, 16, 21, 28, 36, 44 };
int v24[24] = { 5, 20, 48, 86, 128, 171, 215, 256, 296, 318, 333, 340,
333, 321, 293, 257, 214, 170, 127, 82, 45, 20, 5, 0 };
int h12[12] = { 61, 73, 77, 73, 61, 45, 29, 17, 13, 16, 28, 44 };
int v12[12] = { 20, 86, 171, 256, 318, 340, 318, 257, 170, 82, 20, 0 };
char *numbers12[12] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12" };
char *numbers24[24] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18",
"19", "20", "21", "22", "23", "24" };
char *numbers12_a[12] = { "11", "10", "9", "8", "7", "6", "5", "4", "3",
"2", "1", "12" };
char *numbers24_a[24] = { "23", "22", "21", "20", "19", "18", "17", "16",
"15", "14", "13", "12", "11", "10", "9", "8", "7",
"6", "5", "4", "3", "2", "1", "24" };
thymelimit[7] = { 60, 60, 24, 0, 12, 99, 7 };
monthlimit[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned char *screen, *screen0, *screen1, *font ;
int *thyme[7];
char twentyfour=0,location='l';
int main()
{
screen0=abstoptr(SCREEN0);
screen=screen1=abstoptr(SCREEN1);
font=abstoptr(ROMFONT);
system("break off");
g_mode();
#ifdef TICKTOCK
signal (SIGINT, (void (*)(int)) sigexit);
tick_init();
#endif
drawclock();
controller();
t_mode();
scr_clear();
exit(0);
}
void drawclock()
{
int x,y,off,cx=CENTERH,cy=CENTERV,ex=TOPH,ey=TOPV;
long r,xr,yr,xx,yy;
sw_scr(-1);
xr=cx-ex;
yr=cy-ey;
r=sqroot((xr*xr)+(yr*yr))+1;
off=(r*100)/141;
gocircle(cy+(int)r-1,cx);
gocircle(cy-(int)r+1,cx);
for(x=1;x<=off;x++){
xx=x;
xx*=xx;
y=sqroot(r*r-xx);
gocircle(cy+y,cx+x);
gocircle(cy+y,cx-x);
gocircle(cy-y,cx+x);
gocircle(cy-y,cx-x);
}
gocircle(cy,cx+(int)r-1);
gocircle(cy,cx-(int)r+1);
for(y=1;y<=off;y++){
yy=y;
yy*=yy;
x=sqroot(r*r-yy);
gocircle(cy+y,cx+x);
gocircle(cy+y,cx-x);
gocircle(cy-y,cx+x);
gocircle(cy-y,cx-x);
}
markers();
g_write("WALLCLOCK - KITTENSOFT",340,0);
g_write(VERSION,340,64);
if (twentyfour)
for (x=0;x<24;x++) {
if (location=='a')
g_write(numbers24_a[x],v24[x],h24[x]);
else
g_write(numbers24[x],v24[x],h24[x]);
}
else
for (x=0;x<12;x++){
if (location=='a')
g_write(numbers12_a[x],v12[x],h12[x]);
else
g_write(numbers12[x],v12[x],h12[x]);
}
menu();
memcpy(screen1,screen0,32767);
}
void controller()
{
int s,m,h,dh,dm,os,odm,odh,oos,oodm,oodh,q,h24;
struct tm t;
char meridian;
thyme[0]=&(t.tm_sec);
thyme[1]=&(t.tm_min);
thyme[2]=&(t.tm_hour);
thyme[3]=&(t.tm_mday);
thyme[4]=&(t.tm_mon);
thyme[5]=&(t.tm_year);
thyme[6]=&(t.tm_wday);
os=odm=odh=s=dm=dh=1;
for(;;){
switch (inkey()){
case 'X':
case 'q':
case 'Q':
case 'x':
case 3:
return;
case 'a':
case 'A':
location='a';
os=odm=odh=s=dm=dh=1;
drawclock();
break;
case 'l':
case 'L':
location='l';
os=odm=odh=s=dm=dh=1;
drawclock();
break;
case 'c':
case 'C':
dostime(&t);
location='c';
os=odm=odh=s=dm=dh=1;
drawclock();
break;
case 'r':
case 'R':
location='r';
os=odm=odh=s=dm=dh=1;
drawclock();
break;
case '\t':
twentyfour ^=1;
os=odm=odh=s=dm=dh=1;
drawclock();
break;
case 0: break;
}
oos=os;
oodm=odm;
oodh=odh;
os=s;
odm=dm;
odh=dh;
switch (location) {
case 'c':
chinatime();
break;
case 'r':
reagantime(&t);
break;
case 'a':
case 'l':
do dostime(&t);
while (os==t.tm_sec);
break;
}
sw_scr(0);
#ifdef TICKTOCK
tick();
#endif
s=t.tm_sec;
m=t.tm_min;
h=t.tm_hour;
dh=h;
if (twentyfour==0){
if (dh>11) dh-=12;
if (h>11) meridian='P';
else meridian='A';
if (h>12) h-=12;
if (h==0) h=12;
}
dh= dh*60+m;
dm= m*6+s/10;
hand(oos,60,LONG,0,'e');
if (oodm!=dm) hand(oodm,360,LONG,1,'e');
if (oodh!=dh) {
if (twentyfour) hand(oodh,1440,SHORT,1,'e');
else hand(oodh,720,SHORT,1,'e');
}
hand(s,60,LONG,0,'d');
hand(dm,360,LONG,1,'d');
if (twentyfour) hand(dh,1440,SHORT,1,'d');
else hand(dh,720,SHORT,1,'d');
writetd(s,m,h,meridian,&t);
}
}
/* The following toggles the active screen (the one being displayed)
and also toggles the screen pointer (the one being written to) so that
the program is always displaying the screen not being written to. */
void sw_scr(q)
int q;
{
static int scr;
if (q==-1){
screen=screen1;
scr = 0;
memset(screen0,0,32767);
memset(screen1,0,32767);
outportb(CONTROLPORT, 10 | scr);
g_write("Please stand by...",100,30);
}
scr ^= 128;
outportb(CONTROLPORT, 10 | scr);
if (screen==screen0) screen=screen1;
else screen=screen0;
}
#ifdef NOMATH
#include "clock.dat"
void hand(n,num,length,w,q)
int n,num,length,w,q;
{
int v,h;
switch (num) {
case 60: n*=6; break;
case 720: n*=2; break;
}
switch (length) {
case LONG:
h=hlong[n];
v=vlong[n];
break;
case SHORT:
h=hshort[n];
v=vshort[n];
break;
}
if (location=='a') h=((h-CENTERH)*(-1))+CENTERH; /* Austrailia */
line(h,v,CENTERH,CENTERV,q);
if (w) {
line(h+1,v,CENTERH+1,CENTERV,q);
line(h,v+1,CENTERH,CENTERV+1,q);
/* The following 3 lines give the hands better bredth. But they are
very time consuming. Delete them if the